﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using Sherwood.Configuration;

namespace Sherwood.Content.UpdateServices
{
    public static class SearchDocumentUpdater<TRecord> where TRecord : class, IRecord
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(SearchDocumentUpdater<>));

        private static readonly IEnumerable<ISearchDocumentModifier> SearchDocumentModifiers;

        static SearchDocumentUpdater()
        {
            var pluginProvider = DependencyInjection.Resolve<IPluginProvider>();
            SearchDocumentModifiers = pluginProvider.InstantiatePlugins<ISearchDocumentModifier>("SearchDocumentModifiers", true);
        }

        public static void Update(IEnumerable<TRecord> records, int batchSize, bool updateIndexedDate)
        {
            Log.Debug("Entering method Update");

            try
            {
                var searchDocumentService = DependencyInjection.Resolve<ISearchDocumentService>();

                int counter = 0;

                var documents = new List<ISearchDocument>(batchSize);
                foreach (var record in records)
                {
                    if(counter++ % batchSize == 0 && counter > 0)
                    {
                        searchDocumentService.PublishDocuments(documents);
                        documents.Clear();
                    }
                    var searchDocument = searchDocumentService.CreateDocument(record);
                    if (searchDocument != null)
                    {
                        foreach (var updater in SearchDocumentModifiers)
                            updater.Fill(searchDocument, record);

                        documents.Add(searchDocument);
                        if(updateIndexedDate)
                            record.DateIndexed = DateTime.UtcNow;
                    }
                }
                searchDocumentService.PublishDocuments(documents);
            }
            catch (Exception exception)
            {
                Log.Error("Call failed", exception);
                throw;
            }
            finally
            {
                Log.Debug("Leaving method Update");
            }
        }

        public static void Delete(IEnumerable<Guid> recordIds)
        {
            DependencyInjection.Resolve<ISearchDocumentService>().DeleteDocuments(recordIds);
        }
    }
}
